using System;

namespace SmartLib.Common
{
	/// <summary>
	/// Interface for ServiceLocator
	/// </summary>
	public interface IServiceLocator
	{
		/// <summary>
		/// Registers the types.
		/// </summary>
		/// <param name="fromType">From type.</param>
		/// <param name="toType">To type.</param>
		/// <param name="singleton">if set to <c>true</c> [singleton].</param>
		void Register(Type fromType, Type toType, bool singleton);

		/// <summary>
		/// Determines whether the specified type is registered.
		/// </summary>
		/// <param name="fromType">From type.</param>
		/// <param name="toType">To type.</param>
		/// <returns>
		/// 	<c>true</c> if the specified type is registered; otherwise, <c>false</c>.
		/// </returns>
		bool IsRegistered(Type fromType, Type toType);

		/// <summary>
		/// Determines whether [is registered as singleton] [the specified type].
		/// </summary>
		/// <param name="fromType">From type.</param>
		/// <param name="toType">To type.</param>
		/// <returns>
		/// 	<c>true</c> if [is registered as singleton] [the specified type]; otherwise, <c>false</c>.
		/// </returns>
		bool IsRegisteredAsSingleton(Type fromType, Type toType);

		/// <summary>
		/// Resolves the instance by passed type.
		/// </summary>
		/// <typeparam name="T">Cast to desired type</typeparam>
		/// <returns>The instance</returns>
		T Resolve<T>();

		/// <summary>
		/// Resolves the instance by passed type.
		/// </summary>
		/// <typeparam name="T">Cast to desired type</typeparam>
		/// <param name="name">The name of mapped type.</param>
		/// <returns>The instance</returns>
		T Resolve<T>(string name);

		/// <summary>
		/// Resolves the instance by passed type.
		/// </summary>
		/// <typeparam name="T">Cast to desired type</typeparam>
		/// <param name="fromType">From type.</param>
		/// <returns>The instance</returns>
		T Resolve<T>(Type fromType);

		/// <summary>
		/// Resolves the instance by passed type.
		/// </summary>
		/// <typeparam name="T">Cast to desired type</typeparam>
		/// <param name="fromType">From type.</param>
		/// <param name="name">The name of mapped type.</param>
		/// <returns>The instance</returns>
		T Resolve<T>(Type fromType, string name);

		/// <summary>
		/// Creates the instance.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="fromType">From type.</param>
		/// <returns>The instance</returns>
		T CreateInstance<T>(Type fromType);
	}
}